<?php


namespace App\Repositories\Lottery;

use App\Exceptions\BasicException;
use App\Traits\Singleton;
use App\Models\MainDB\User as MainUserModel;
use App\Models\MainDB\Lottery\User as Model;
use App\Models\MainDB\Lottery\BalanceLog as BalanceLogModel;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use App\Models\MainDB\AccountLog;

class UserRepository
{
    use Singleton;

    public function info(int $userId)
    {
        $query = app('model_user_account')::query();
        $query->where('user_id', $userId);
        return $query->first();
    }

    public function swap(int $userId, int $count)
    {
        DB::beginTransaction();
        try {
            $setting = SettingRepository::getInstance()->one([], true); // 游戏配置
            if (!$setting || !$setting->is_open) {
                throw new BasicException('游戏未开启');
            }
            $coin = $count * $setting->balance_coin;
            $this->decUserMoney($userId, $coin);
            app('model_account_log')->addLog($userId, $coin, "兑换游戏道具x{$count}", 224);
            $user = Model::query()->where('id', $userId)->lockForUpdate()->first();
            if (!$user) {
                $user = Model::create(['id' => $userId, 'balance' => $count, 'total_balance' => $count]);
            } else {
                $user->balance       += $count;
                $user->total_balance += $count;
                $user->save();
            }
            BalanceLogModel::create([
                'user_id' => $userId,
                'source'  => BalanceLogModel::SWAP_BALANCE,
                'amount'  => $count,
                'balance' => $user->balance,
            ]);
            DB::commit();
        } catch (\Exception $exception) {
            DB::rollBack();
            throw new BasicException(-1, '兑换失败' . $exception->getMessage());
        }
        return $user;
    }

    public function decUserMoney(int $userId, int $coin)
    {
        $mainUser = MainUserModel::where('user_id', $userId)->lockForUpdate()->firstOrFail();
        if ($mainUser->money < $coin) {
            throw new BasicException(-1, '用户金币不足');
        }
        $mainUser->money -= $coin;
        $mainUser->save();
    }

    public function one(array $condition = [], bool $fail = false, bool $lock = false)
    {
        $query = Model::query();
        $query->where($condition);
        if ($lock) {
            $query->lockForUpdate();
        }
        $query->with(['date' => function ($with) {
            $with->where('date', '=', Carbon::now()->format("Y-m-d"));
        }]);
        return $fail == true ? $query->firstOrFail() : $query->first();
    }

    public function find(int $id, bool $fail = false, bool $lock = false)
    {
        return $this->one(['id' => $id], $fail, $lock);
    }

    public function create(array $data)
    {
        $model = new Model();
        $model->fill($data);
        $model->save();
        $model->refresh();

        return $model;
    }

}